package com.tongji.diy.view.component3D
{
	import com.tongji.diy.event.AddShapeEvent;
	import com.tongji.diy.event.UploadRoomBorderEvent;
	import com.tongji.diy.model.RoomBorderChild;
	import com.tongji.diy.model.RoomControlPointArc;
	import com.tongji.diy.model.WallHole;
	import com.tongji.diy.utils.ArcBorderUtils;
	import com.tongji.diy.utils.RoomParameters;
	import com.tongji.diy.view.filter.DefaultFilter;
	import com.tongji.diy.view.filter.SelectFilter;
	import com.tongji.diy.view.material.DefaultMaterial;
	import com.tongji.diy.view.material.WhiteMaterial;
	
	import de.polygonal.ds.DListNode;
	
	import flare.basic.Scene3D;
	import flare.collisions.MouseCollision;
	import flare.core.Mesh3D;
	import flare.core.Pivot3D;
	import flare.core.Shape3D;
	import flare.core.Surface3D;
	import flare.core.Texture3D;
	import flare.materials.Material3D;
	import flare.materials.Shader3D;
	import flare.materials.filters.TextureFilter;
	import flare.primitives.Plane;
	import flare.system.Input3D;
	
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.events.Event;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	
	import mx.messaging.AbstractConsumer;
	
	import org.robotlegs.mvcs.Actor;
	
	/**
	 * 
	 * @author xxj
	 * 
	 */
	
	public class RoomBorder extends BaseRoomBorder
	{
		private var _needToUpload:Boolean = false;
		public var material:Material3D;
		public var start:DListNode;
		public var end:DListNode;
		public var lock:Boolean;
		private const N:uint = ArcBorderUtils.N;
		private var decoFilter:TextureFilter;
		private const STEP:Number = ArcBorderUtils.STEP;
		
		private var _selected:Boolean = false;

		//保存上一帧的位置
		public var lastPosition:Point = new Point();
		//指向此墙外侧的法向量
		public var normalVec:Point = new Point();
		
		//存门洞，窗洞
		private var holeVector:Vector.<WallHole> = new Vector.<WallHole>();
		
		public var doorVector:Vector.<Door> = new Vector.<Door>();
		
		public function RoomBorder(start:DListNode, end:DListNode, material:Material3D)
		{
			this.start = start;
			start.data.nextBorder = this;
			this.end = end;
			end.data.prevBorder = this;
			
			var shader:Shader3D = material.clone() as Shader3D;
			if(shader.filters.length > 1)
				shader.filters.pop();
			this.material = shader as Material3D;
			
			super();
			
			//内墙
			surfaces[0] = new Surface3D();
			surfaces[0].material = this.material.clone();
			surfaces[0].addVertexData( Surface3D.POSITION );
			surfaces[0].addVertexData( Surface3D.UV0 );
			surfaces[0].addVertexData( Surface3D.UV1 );
			surfaces[0].addVertexData( Surface3D.NORMAL );
			//墙顶
			surfaces[1] = new Surface3D();
			surfaces[1].material = DefaultMaterial.getInst();
			surfaces[1].addVertexData( Surface3D.POSITION );
			surfaces[1].addVertexData( Surface3D.UV0 );
			surfaces[1].addVertexData( Surface3D.NORMAL );
			//外墙
			surfaces[2] = new Surface3D();
			surfaces[2].material = DefaultMaterial.getInst();
			surfaces[2].addVertexData( Surface3D.POSITION );
			surfaces[2].addVertexData( Surface3D.UV0 );
			surfaces[2].addVertexData( Surface3D.NORMAL );
			//墙洞内壁
//			surfaces[3] = new Surface3D();
//			surfaces[3].material = DefaultMaterial.getInst();
//			surfaces[3].addVertexData( Surface3D.POSITION );
//			surfaces[3].addVertexData( Surface3D.UV0 );
//			surfaces[3].addVertexData( Surface3D.NORMAL );
			
			/*
			 *	计算顶点
			 */
			
			var currentNode:DListNode; //data属性为当前控制点
			var insidePoint:Point;     //内墙顶点坐标
			var outsidePoint:Point;    //外墙顶点坐标
			var prevVector:Point;      //当前控制点到前一控制点向量
			var nextVector:Point;      //当前控制点到后一控制点向量
			var insideVector:Point;    //当前控制点向房间内部的向量
			
			//保存可能邻接的弧形墙的顶点数据
			var points:Vector.<Point>;
			var roomControlPointArc:RoomControlPointArc;
			
			//前
			currentNode = start;
			if(currentNode.prev.data is RoomControlPointArc)
			{
				roomControlPointArc = currentNode.prev.data as RoomControlPointArc;
				points = roomControlPointArc.arcBorderShape;
				prevVector = new Point( points[points.length-3].x - currentNode.data.x, points[points.length-3].y - currentNode.data.y);
			}
			else
				prevVector = new Point( currentNode.prev.data.x - currentNode.data.x, currentNode.prev.data.y - currentNode.data.y);
			if(currentNode.next.data is RoomControlPointArc)
			{
				roomControlPointArc = currentNode.next.data as RoomControlPointArc;
				points = roomControlPointArc.arcBorderShape;
				nextVector = new Point( points[2].x - currentNode.data.x, points[2].y - currentNode.data.y)
			}
			else
				nextVector = new Point( currentNode.next.data.x - currentNode.data.x, currentNode.next.data.y - currentNode.data.y);
			insideVector = getInsideVector(prevVector,nextVector);
			insidePoint = new Point(currentNode.data.x + insideVector.x, currentNode.data.y + insideVector.y);
			outsidePoint = new Point(currentNode.data.x - insideVector.x, currentNode.data.y - insideVector.y);
			
			//0
			surfaces[0].vertexVector.push(insidePoint.x, 0, insidePoint.y, 0, 0, 0, 0, 0, 1, 1);
			//1
			surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 0, 1, 0, 1, 0, 1, 0);
			
			//1
			surfaces[1].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 0, 0, 0, 1, 0);
			//2
			surfaces[1].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 0, 1, 0, 1, 0);
			
			//2
			surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 1, 1, 0, 1, 0);
			//3
			surfaces[2].vertexVector.push(outsidePoint.x, 0, outsidePoint.y, 1, 0, 0, 1, 1);
			
			//后
			currentNode = end;
			if(currentNode.prev.data is RoomControlPointArc)
			{
				roomControlPointArc = currentNode.prev.data as RoomControlPointArc;
				points = roomControlPointArc.arcBorderShape;
				prevVector = new Point( points[points.length-3].x - currentNode.data.x, points[points.length-3].y - currentNode.data.y);
			}
			else
				prevVector = new Point( currentNode.prev.data.x - currentNode.data.x, currentNode.prev.data.y - currentNode.data.y);
			if(currentNode.next.data is RoomControlPointArc)
			{
				roomControlPointArc = currentNode.next.data as RoomControlPointArc;
				points = roomControlPointArc.arcBorderShape;
				nextVector = new Point( points[2].x - currentNode.data.x, points[2].y - currentNode.data.y)
			}
			else
				nextVector = new Point( currentNode.next.data.x - currentNode.data.x, currentNode.next.data.y - currentNode.data.y);
			insideVector = getInsideVector(prevVector,nextVector);
			insidePoint = new Point(currentNode.data.x + insideVector.x, currentNode.data.y + insideVector.y);
			outsidePoint = new Point(currentNode.data.x - insideVector.x, currentNode.data.y - insideVector.y);
			
			//4
			surfaces[0].vertexVector.push(insidePoint.x, 0, insidePoint.y, 1, 0, 1, 0, 0, 1, 1);
			//5
			surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 1, 1, 1, 1, 0, 1, 0);
			
			//5
			surfaces[1].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 1, 0, 0, 1, 0);
			//6
			surfaces[1].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 1, 1, 0, 1, 0);
			
			//6
			surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 0, 1, 0, 1, 0);
			//7
			surfaces[2].vertexVector.push(outsidePoint.x, 0, outsidePoint.y, 0, 0, 0, 1, 1);
			
			//内墙
			surfaces[0].indexVector.push(0,1,2,2,1,3);
			//墙顶
			surfaces[1].indexVector.push(0,1,2,2,1,3);
			//外墙
			surfaces[2].indexVector.push(3,2,1,1,2,0);
			
			//更新贴图大小
			//内墙
			shader = surfaces[0].material as Shader3D;
			var texFilter:TextureFilter = shader.filters[0] as TextureFilter;
			var point:Point = new Point(surfaces[0].vertexVector[0] - surfaces[0].vertexVector[20], surfaces[0].vertexVector[2] - surfaces[0].vertexVector[22]);
			texFilter.repeatX = point.length/150;
			//墙顶
			shader = surfaces[1].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			point = new Point(surfaces[1].vertexVector[0] - surfaces[1].vertexVector[16], surfaces[1].vertexVector[2] - surfaces[1].vertexVector[18]);
			texFilter.repeatX = point.length/150;
			//外墙
			shader = surfaces[2].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			point = new Point(surfaces[2].vertexVector[0] - surfaces[2].vertexVector[16], surfaces[2].vertexVector[2] - surfaces[2].vertexVector[18]);
			texFilter.repeatX = point.length/150;
			
			_needToUpload = true;
		}
		
		//根据前向量和后向量计算向房间内的向量
		private function getInsideVector(prevVector:Point, nextVector:Point):Point
		{
			var angle:Number = Math.acos(getCos(prevVector,nextVector));
			var distance:Number = RoomParameters.wallWidth/Math.sin(angle/2);
			var prevAngle:Number = Math.atan(prevVector.y/prevVector.x);
			if (prevVector.x<0)
			{
				prevAngle = prevAngle - Math.PI;
			}	
			var nextAngle:Number = Math.atan(nextVector.y/nextVector.x);
			if (nextVector.x<0)
			{
				nextAngle = nextAngle - Math.PI;
			}
			var middleAngle	:Number = (nextAngle + prevAngle) /2
			
			var insideVector:Point = new Point(Math.cos(middleAngle) * distance, Math.sin(middleAngle) * distance);
			if (isClockwise(-prevVector.x, -prevVector.y, 0, 0, insideVector.x,insideVector.y))
			{
				insideVector.x = -insideVector.x;
				insideVector.y = -insideVector.y;
			}
			return insideVector;
		}
		
		public function addDoor(door:Door,mouse:MouseCollision):void
		{
			var doorPos:Vector3D = door.getPosition(false);
			var room:Room = this.parent as Room;
			doorPos = room.globalToLocal(doorPos);
			door.setPosition(doorPos.x,doorPos.y,doorPos.z);
			var pos:Point = new Point(doorPos.x,doorPos.z);
			/*var wallHole:WallHole = new WallHole(pos,door.width,door.top,door.bottom);
			addHole(wallHole,mouse);*/
//			var door:Door = new Door(door.wallDoor,doorPos,this);
			this.doorVector.push(door);
			this.addChild(door);
		}
		
		public function addHole(hole:WallHole,mouse:MouseCollision):void
		{
			lock = true;
			start.data.prevBorder.lock = true;
			end.data.nextBorder.lock = true;
			start.data.vertex.lock = true;
			end.data.vertex.lock = true;
			var index:uint = holeVector.length;
			for (var i:uint = 0; i< holeVector.length; i++)
			{
				if (getStartDistance(holeVector[i]) > getStartDistance(hole))
				{
					index = i;
					break;
				}
			}
			//trace ("holeVector",index);
			holeVector.splice(index,0,hole);
			refresh(mouse);
		}
		
		//到start点的距离平方
		private function getStartDistance(hole:RoomBorderChild):Number
		{
			return (hole.position.x - start.data.x)*(hole.position.x - start.data.x)+(hole.position.y - start.data.y)*(hole.position.y - start.data.y)
		}
		
		override public function refresh(mouse:MouseCollision):void
		{
			mouse.removeCollisionWith(this);
			
			//因为每次刷新都要dispose，所以保存之前的材质
			var mat0:Material3D = surfaces[0].material;
			
			//要算uv就必须分别得到前后面的前后点位置
			var ist:Point;
			var ied:Point;
			var ost:Point;
			var oed:Point;
			
			//内墙
			surfaces[0].dispose();
			surfaces[0] = new Surface3D();
			surfaces[0].material = mat0;
			surfaces[0].addVertexData( Surface3D.POSITION );
			surfaces[0].addVertexData( Surface3D.UV0 );
			surfaces[0].addVertexData( Surface3D.UV1 );
			surfaces[0].addVertexData( Surface3D.NORMAL );
			//墙顶
			surfaces[1].dispose();
			surfaces[1] = new Surface3D();
			surfaces[1].material = DefaultMaterial.getInst();
			surfaces[1].addVertexData( Surface3D.POSITION );
			surfaces[1].addVertexData( Surface3D.UV0 );
			surfaces[1].addVertexData( Surface3D.NORMAL );
			//外墙
			surfaces[2].dispose();
			surfaces[2] = new Surface3D();
			surfaces[2].material = DefaultMaterial.getInst();
			surfaces[2].addVertexData( Surface3D.POSITION );
			surfaces[2].addVertexData( Surface3D.UV0 );
			surfaces[2].addVertexData( Surface3D.NORMAL );
			//墙洞内壁
			if(holeVector.length > 0)
			{
				if(surfaces.length == 4)
					surfaces[3].dispose();
				surfaces[3] = new Surface3D();
				surfaces[3].material = WhiteMaterial.getInst();
				surfaces[3].addVertexData( Surface3D.POSITION );
				surfaces[3].addVertexData( Surface3D.UV0 );
				surfaces[3].addVertexData( Surface3D.NORMAL );
			}
			
			//算点
			var currentNode:DListNode; //data属性为当前控制点
			var insidePoint:Point;     //内墙顶点坐标
			var outsidePoint:Point;    //外墙顶点坐标
			var prevVector:Point;      //当前控制点到前一控制点向量
			var nextVector:Point;      //当前控制点到后一控制点向量
			var insideVector:Point;    //当前控制点向房间内部的向量
			
			//保存可能邻接的弧形墙的顶点数据
			var points:Vector.<Point>;
			
			//前
			currentNode = start;
			if(currentNode.prev.data is RoomControlPointArc)
			{
				var sP:Point = new Point(currentNode.prev.prev.data.x,currentNode.prev.prev.data.y);
				var cP:Point = new Point(currentNode.prev.data.x,currentNode.prev.data.y);
				var eP:Point = new Point(currentNode.data.x,currentNode.data.y);
				var j:uint = uint(1.00/STEP)-1;
				var p:Point = new Point();
				p.x = sP.x*ArcBorderUtils.bez(N,0,j*STEP)+cP.x*ArcBorderUtils.bez(N,1,j*STEP)+eP.x*ArcBorderUtils.bez(N,2,j*STEP);
				p.y = sP.y*ArcBorderUtils.bez(N,0,j*STEP)+cP.y*ArcBorderUtils.bez(N,1,j*STEP)+eP.y*ArcBorderUtils.bez(N,2,j*STEP);
				
				prevVector = new Point( p.x - currentNode.data.x, p.y - currentNode.data.y);
			}
			else
				prevVector = new Point( currentNode.prev.data.x - currentNode.data.x, currentNode.prev.data.y - currentNode.data.y);
			if(currentNode.next.data is RoomControlPointArc)
			{
				points = currentNode.data.nextBorder.points;
				nextVector = new Point( points[2].x - currentNode.data.x, points[2].y - currentNode.data.y);
			}
			else
				nextVector = new Point( currentNode.next.data.x - currentNode.data.x, currentNode.next.data.y - currentNode.data.y);
			insideVector = getInsideVector(prevVector,nextVector);
			insidePoint = new Point(currentNode.data.x + insideVector.x, currentNode.data.y + insideVector.y);
			outsidePoint = new Point(currentNode.data.x - insideVector.x, currentNode.data.y - insideVector.y);
			
			ist = insidePoint;
			ost = outsidePoint;
			
			//0
			surfaces[0].vertexVector.push(insidePoint.x, 0, insidePoint.y,
				0, 0,
				0, 0,
				0, 1, 1);
			
			surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight/4, insidePoint.y,
				0, 1/4, 
				0, 1/4,
				0, 1, 3/4);
			surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight/2, insidePoint.y,
				0, 1/2,
				0, 1/2,
				0, 1, 2/1);
			//1
			surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y,
				0, 1, 
				0, 1, 
				0, 1, 0);
			
			//1
			surfaces[1].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 
				0, 0,
				0, 1, 0);
			//2
			surfaces[1].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y,
				0, 1,
				0, 1, 0);
			
			//3
			surfaces[2].vertexVector.push(outsidePoint.x, 0, outsidePoint.y, 
				1, 0,
				0, 1, 1);
			surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight/4, outsidePoint.y, 
				1, 1/4,
				0, 1, 3/4);
			surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight/2, outsidePoint.y,
				1, 1/2,
				0, 1, 2/1);
			//2
			surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 
				1, 1, 
				0, 1, 0);
			
			//
			//中间的横截面
			//WARNING:墙洞内壁没考虑uv
			//后
			currentNode = end;
			if(currentNode.prev.data is RoomControlPointArc)
			{
				points = currentNode.data.prevBorder.points;
				prevVector = new Point( points[points.length-3].x - currentNode.data.x, points[points.length-3].y - currentNode.data.y);
			}
			else
				prevVector = new Point( currentNode.prev.data.x - currentNode.data.x, currentNode.prev.data.y - currentNode.data.y);
			if(currentNode.next.data is RoomControlPointArc)
			{
				sP = new Point(currentNode.data.x,currentNode.data.y);
				cP = new Point(currentNode.next.data.x,currentNode.next.data.y);
				eP = new Point(currentNode.next.next.data.x,currentNode.next.next.data.y);
				j = 1;
				p = new Point();
				p.x = sP.x*ArcBorderUtils.bez(N,0,j*STEP)+cP.x*ArcBorderUtils.bez(N,1,j*STEP)+eP.x*ArcBorderUtils.bez(N,2,j*STEP);
				p.y = sP.y*ArcBorderUtils.bez(N,0,j*STEP)+cP.y*ArcBorderUtils.bez(N,1,j*STEP)+eP.y*ArcBorderUtils.bez(N,2,j*STEP);
				
				nextVector = new Point( p.x - currentNode.data.x, p.y - currentNode.data.y);
			}
			else
				nextVector = new Point( currentNode.next.data.x - currentNode.data.x, currentNode.next.data.y - currentNode.data.y);
			insideVector = getInsideVector(prevVector,nextVector);
			insidePoint = new Point(currentNode.data.x + insideVector.x, currentNode.data.y + insideVector.y);
			outsidePoint = new Point(currentNode.data.x - insideVector.x, currentNode.data.y - insideVector.y);
			
			//计算UV所需顶点位置
			ied = insidePoint;
			oed = outsidePoint;
			
			var iDelta:Number = Point.distance(ied,ist);
			var oDelta:Number = Point.distance(oed,ost);
			
			for (var i:uint = 0; i<holeVector.length; i++)
			{
				var leftInsidePoint:Point;
				var rightInsidePoint:Point;
				var leftOutsidePoint:Point;
				var rightOutsidePoint:Point;
				var currentHole:WallHole = holeVector[i] as WallHole;
				//
				//仅仅是为了算内墙法向量的方向向量
				prevVector = new Point( start.data.x - end.data.x, start.data.y - end.data.y);
				nextVector = new Point( end.data.x - start.data.x, end.data.y - start.data.y);
				insideVector = getInsideVector(prevVector,nextVector);
				//
				//虽不懂，但可用
				prevVector.normalize(1);
				nextVector.normalize(1);
				insidePoint = new Point(currentHole.position.x + insideVector.x, currentHole.position.y + insideVector.y);
				outsidePoint = new Point(currentHole.position.x - insideVector.x, currentHole.position.y - insideVector.y);
				leftInsidePoint = new Point(insidePoint.x + prevVector.x*currentHole.width/2, insidePoint.y + prevVector.y*currentHole.width/2 );
				leftOutsidePoint = new Point(outsidePoint.x + prevVector.x*currentHole.width/2, outsidePoint.y + prevVector.y*currentHole.width/2 );
				rightInsidePoint = new Point(insidePoint.x + nextVector.x*currentHole.width/2, insidePoint.y + nextVector.y*currentHole.width/2 );
				rightOutsidePoint = new Point(outsidePoint.x + nextVector.x*currentHole.width/2, outsidePoint.y + nextVector.y*currentHole.width/2 );
				//
				//内墙靠start点的顶点
				//内墙
				//左内侧UV
				var liUVx:Number = Point.distance(leftInsidePoint,ist)/iDelta;
				surfaces[0].vertexVector.push(leftInsidePoint.x, 0, leftInsidePoint.y, 
					liUVx, 0,
					liUVx, 0,
					0, 1, 1);
				surfaces[0].vertexVector.push(leftInsidePoint.x, currentHole.bottom, leftInsidePoint.y,
					liUVx, currentHole.bottom/RoomParameters.wallHeight,
					liUVx, currentHole.bottom/RoomParameters.wallHeight,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[0].vertexVector.push(leftInsidePoint.x, currentHole.top, leftInsidePoint.y,
					liUVx, currentHole.top/RoomParameters.wallHeight,
					liUVx, currentHole.top/RoomParameters.wallHeight,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				surfaces[0].vertexVector.push(leftInsidePoint.x, RoomParameters.wallHeight, leftInsidePoint.y,
					liUVx, 1,
					liUVx, 1,
					0, 1, 0);
				//墙洞内壁
				surfaces[3].vertexVector.push(leftInsidePoint.x, currentHole.bottom, leftInsidePoint.y,
					liUVx, currentHole.bottom/RoomParameters.wallHeight,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[3].vertexVector.push(leftInsidePoint.x, currentHole.top, leftInsidePoint.y,
					liUVx, currentHole.top/RoomParameters.wallHeight,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				//
				//外墙靠start点的顶点
				//外墙
				//左外侧UV，因为外侧是从右向左所以要用1减，下同
				var loUVx:Number = Point.distance(leftOutsidePoint,ost)/oDelta;
				surfaces[2].vertexVector.push(leftOutsidePoint.x, 0, leftOutsidePoint.y,
					1-loUVx, 0,
					0, 1, 1);
				surfaces[2].vertexVector.push(leftOutsidePoint.x, currentHole.bottom, leftOutsidePoint.y,
					1-loUVx, currentHole.bottom/RoomParameters.wallHeight,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[2].vertexVector.push(leftOutsidePoint.x, currentHole.top, leftOutsidePoint.y, 
					1-loUVx, currentHole.top/RoomParameters.wallHeight,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				surfaces[2].vertexVector.push(leftOutsidePoint.x, RoomParameters.wallHeight, leftOutsidePoint.y,
					1-loUVx, 1,
					0, 1, 0);
				//墙洞内壁
				surfaces[3].vertexVector.push(leftOutsidePoint.x, currentHole.bottom, leftOutsidePoint.y,
					0, 0,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[3].vertexVector.push(leftOutsidePoint.x, currentHole.top, leftOutsidePoint.y, 
					0, 0,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				//
				//内墙靠end点的顶点
				//右内侧UV
				var riUVx:Number = Point.distance(rightInsidePoint,ist)/iDelta;
				surfaces[0].vertexVector.push(rightInsidePoint.x, 0, rightInsidePoint.y,
					riUVx, 0,
					riUVx, 0,
					0, 1, 1);
				surfaces[0].vertexVector.push(rightInsidePoint.x, currentHole.bottom, rightInsidePoint.y,
					riUVx, currentHole.bottom/RoomParameters.wallHeight,
					riUVx, currentHole.bottom/RoomParameters.wallHeight,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[0].vertexVector.push(rightInsidePoint.x, currentHole.top, rightInsidePoint.y,
					riUVx, currentHole.top/RoomParameters.wallHeight,
					riUVx, currentHole.top/RoomParameters.wallHeight,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				surfaces[0].vertexVector.push(rightInsidePoint.x, RoomParameters.wallHeight, rightInsidePoint.y,
					riUVx, 1, 
					riUVx, 1, 
					0, 1, 0);
				//墙洞内壁
				surfaces[3].vertexVector.push(rightInsidePoint.x, currentHole.bottom, rightInsidePoint.y,
					0, 0,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[3].vertexVector.push(rightInsidePoint.x, currentHole.top, rightInsidePoint.y,
					0, 0, 
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				//
				//外墙靠end点的顶点
				//右外侧UV
				var roUVx:Number = Point.distance(rightOutsidePoint,ost)/oDelta;
				surfaces[2].vertexVector.push(rightOutsidePoint.x, 0, rightOutsidePoint.y,
					1-roUVx, 0, 
					0, 1, 1);
				surfaces[2].vertexVector.push(rightOutsidePoint.x, currentHole.bottom, rightOutsidePoint.y, 
					1-roUVx, currentHole.bottom/RoomParameters.wallHeight,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[2].vertexVector.push(rightOutsidePoint.x, currentHole.top, rightOutsidePoint.y, 
					1-roUVx, currentHole.top/RoomParameters.wallHeight,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				surfaces[2].vertexVector.push(rightOutsidePoint.x, RoomParameters.wallHeight, rightOutsidePoint.y, 
					1-roUVx, 1, 
					0, 1, 0);
				//墙洞内壁
				surfaces[3].vertexVector.push(rightOutsidePoint.x, currentHole.bottom, rightOutsidePoint.y, 
					0, 0,
					0, 1, 1-currentHole.bottom/RoomParameters.wallHeight);
				surfaces[3].vertexVector.push(rightOutsidePoint.x, currentHole.top, rightOutsidePoint.y, 
					0, 0,
					0, 1, 1-currentHole.top/RoomParameters.wallHeight);
				//内墙洞左下角顶点index
				var baseIndex:uint = 8 * i;
				//墙洞内壁4墙面 
				surfaces[3].indexVector.push(baseIndex+0,baseIndex+1,baseIndex+2,baseIndex+2,baseIndex+1,baseIndex+3);
				surfaces[3].indexVector.push(baseIndex+1,baseIndex+7,baseIndex+3,baseIndex+7,baseIndex+1,baseIndex+5);
				surfaces[3].indexVector.push(baseIndex+7,baseIndex+5,baseIndex+6,baseIndex+6,baseIndex+5,baseIndex+4);
				surfaces[3].indexVector.push(baseIndex+2,baseIndex+6,baseIndex+0,baseIndex+0,baseIndex+6,baseIndex+4);
			}
			
			//4
			surfaces[0].vertexVector.push(ied.x, 0, ied.y,
				1, 0, 
				1, 0,
				0, 1, 1);
			surfaces[0].vertexVector.push(ied.x, RoomParameters.wallHeight/4, ied.y,
				1, 1/4, 
				1, 1/4,
				0, 1, 3/4);
			surfaces[0].vertexVector.push(ied.x, RoomParameters.wallHeight/2, ied.y,
				1, 1/2, 
				1, 1/2,
				0, 1, 2/1);
			//5
			surfaces[0].vertexVector.push(ied.x, RoomParameters.wallHeight, ied.y,
				1, 1,
				1, 1,
				0, 1, 0);
			
			//5
			surfaces[1].vertexVector.push(ied.x, RoomParameters.wallHeight, ied.y,
				1, 0, 
				0, 1, 0);
			//6
			surfaces[1].vertexVector.push(oed.x, RoomParameters.wallHeight, oed.y, 
				1, 1,
				0, 1, 0);
			
			//7
			surfaces[2].vertexVector.push(oed.x, 0, oed.y, 
				0, 0,
				0, 1, 1);
			surfaces[2].vertexVector.push(oed.x, RoomParameters.wallHeight/4, oed.y,
				0, 1/4,
				0, 1, 3/4);
			surfaces[2].vertexVector.push(oed.x, RoomParameters.wallHeight/2, oed.y,
				0, 1/2,
				0, 1, 2/1);
			//6
			surfaces[2].vertexVector.push(oed.x, RoomParameters.wallHeight, oed.y,
				0, 1,
				0, 1, 0);
			
			//
			//顶点8个一组一个横截面，一次保存2个面，所以这样来做索引
			for (i = 1; i<surfaces[0].vertexVector.length/10/4; i++)
			{
				baseIndex = 4*i-4;
				if (i%2==1)
				{
					//内墙
					surfaces[0].indexVector.push(baseIndex+0,baseIndex+3,baseIndex+4,baseIndex+4,baseIndex+3,baseIndex+7);
					//外墙
					surfaces[2].indexVector.push(baseIndex+0,baseIndex+4,baseIndex+3,baseIndex+4,baseIndex+7,baseIndex+3);
				}
				else
				{
					//内墙
					surfaces[0].indexVector.push(baseIndex+2,baseIndex+3,baseIndex+6,baseIndex+6,baseIndex+3,baseIndex+7);
					surfaces[0].indexVector.push(baseIndex+0,baseIndex+1,baseIndex+4,baseIndex+4,baseIndex+1,baseIndex+5);
					//外墙
					surfaces[2].indexVector.push(baseIndex+2,baseIndex+6,baseIndex+3,baseIndex+6,baseIndex+7,baseIndex+3);
					surfaces[2].indexVector.push(baseIndex+0,baseIndex+4,baseIndex+1,baseIndex+4,baseIndex+5,baseIndex+1);
				}
			}
			//墙顶
			surfaces[1].indexVector.push(0,1,2,2,1,3);
			
			surfaces[0].upload(this.scene);
			surfaces[1].upload(this.scene);
			surfaces[2].upload(this.scene);
			if(holeVector.length > 0)
				surfaces[3].upload(this.scene);
			
			//更新贴图大小
			//内墙
			var shader:Shader3D = surfaces[0].material as Shader3D;
			var texFilter:TextureFilter = shader.filters[0] as TextureFilter;
			texFilter.repeatX = (ied.subtract(ist)).length/150;
			
			//墙顶
			shader = surfaces[1].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			texFilter.repeatX = (ied.subtract(ist)).length/150;
			
			//外墙
			shader = surfaces[2].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			texFilter.repeatX = (oed.subtract(ost)).length/150;
			
			//墙洞内壁无需更新贴图
			
			_needToUpload = true;
			
			//每次修改mesh都要重新计算Bounding，否则无法正常做鼠标Collision
			this.updateBoundings();
			
			mouse.addCollisionWith(this);
		}
		
		public function selectEffect():void
		{
			var shader:Shader3D = this.surfaces[0].material as Shader3D;
			if(shader.filters.length == 1)
			{
				shader.filters.push(SelectFilter.getInst());
				shader.build();
				this.surfaces[0].material = shader as Material3D;
				this._selected = true;
			}
		}
		
		public function unSelect():void
		{
			if(this.surfaces)
			{
				var shader:Shader3D = this.surfaces[0].material as Shader3D;
				if(shader.filters.length == 2)
				{
					shader.filters.pop();
					shader.build();
					this.surfaces[0].material = shader as Material3D;
					this._selected = false;
				}
			}
		}
		
		public function get selected():Boolean
		{
			return this._selected;
		}
		
		protected function isClockwise(x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number):Boolean
		{
			if (x0 * y1 + x1 * y2 + x2 * y0 - x1 * y0 - x2 * y1 - x0 * y2 <= 0)
				return true;
			else
				return false;
		}
		
		override public function upload(scene:Scene3D = null, force:Boolean = false, includeChildren:Boolean = true ):Boolean
		{
			_needToUpload = false;
			
			if ( super.upload( scene, force, includeChildren ) == false ) return false;
			
			return true;
		}
		
		public override function draw( includeChildren:Boolean = false ):void 
		{
			if ( _needToUpload && scene ) upload( scene );
			
			if ( _needToUpload ) return;
			
			super.draw( includeChildren );
		}
		
		//拖动前的准备
		public function startDragHandler():void
		{
			//每次移动前初始化该值
			lastPosition.x = 0;
			lastPosition.y = 0;
			
			//获取当前墙的法向量
			normalVec = getNormal();
		}
		
		//拖动时派发消息，改变与当前墙相邻的左右2面墙
		//向量还可单位化以提高性能
		public function dragAct():void
		{
			var startPosition:Point = new Point();
			var endPosition:Point = new Point();
			//每帧鼠标移动的增量
			var currentVec:Point = new Point(this.x-this.lastPosition.x, this.z-this.lastPosition.y);
			
			//得到在墙移动方向上的投影的长度
			var offset:Number = this.getCos( currentVec, this.normalVec )*currentVec.length;
			
			//左右两边墙的方向向量，与当前墙的法向量同向
			var leftVec:Point = new Point( this.start.data.x - this.start.prev.data.x, this.start.data.y - this.start.prev.data.y);
			var rightVec:Point = new Point( this.end.data.x - this.end.next.data.x, this.end.data.y - this.end.next.data.y);
			
			//左右两边墙的长度增量
			var leftOffsetLength:Number = offset / this.getCos( leftVec, this.normalVec );
			var rightOffsetLength:Number = offset / this.getCos( rightVec, this.normalVec );
			
			//左右两边墙在平面坐标系各轴上的增量
			var leftOffset:Point = new Point( leftOffsetLength/Math.sqrt( leftVec.x*leftVec.x + leftVec.y*leftVec.y )*leftVec.x,
				leftOffsetLength/Math.sqrt( leftVec.x*leftVec.x + leftVec.y*leftVec.y )*leftVec.y );
			
			var rightOffset:Point = new Point(	rightOffsetLength/Math.sqrt( rightVec.x*rightVec.x + rightVec.y*rightVec.y )*rightVec.x,
				rightOffsetLength/Math.sqrt( rightVec.x*rightVec.x + rightVec.y*rightVec.y )*rightVec.y );
			
			//计算最终要传入的新墙的左右2点的位置
			startPosition.x = this.start.data.x + leftOffset.x;
			startPosition.y = this.start.data.y + leftOffset.y;
			
			endPosition.x = this.end.data.x + rightOffset.x;
			endPosition.y = this.end.data.y + rightOffset.y;
			
			//保存这一帧的位置
			this.lastPosition.x = this.x;
			this.lastPosition.y = this.z;
			
			//派发事件数据到dispatch
			this.scene.dispatchEvent(new UploadRoomBorderEvent( UploadRoomBorderEvent.UPLOAD_ROOM_BORDER, this, startPosition, endPosition));
		}
		
		//指向当前墙外侧的法向量
		public function getNormal():Point
		{
			var vec:Point = new Point( this.start.data.globalX - this.end.data.globalX, this.start.data.globalY - this.end.data.globalY);
			var normal:Point = new Point(-vec.y, vec.x);
			//左邻墙体的方向向量，指向当前墙的外侧
			var leftBorderVec:Point = new Point( this.start.data.globalX - this.start.prev.data.globalX, this.start.data.globalY - this.start.prev.data.globalY);
			
			var newPoint:Point;
			//反向则求负后传值，且单位化
			if( normal.x*leftBorderVec.x+normal.y*leftBorderVec.y > 0 )
				newPoint = new Point(normal.x/normal.length, normal.y/normal.length);
			else
				newPoint = new Point(-normal.x/normal.length, -normal.y/normal.length);
			if (!isClockwise( end.data.x-start.data.x,end.data.y-start.data.y,0,0,newPoint.x,newPoint.y))
			{
				newPoint.x = -newPoint.x;
				newPoint.y = -newPoint.y 
			}
			return newPoint;
		}
		
		//求vec1和vec2夹角的余弦值
		private function getCos( vec1:Point, vec2:Point ):Number
		{
			if(vec1.length == 0 || vec2.length == 0)
				return 0;
			return ( ( vec1.x*vec2.x + vec1.y*vec2.y ) / (vec1.length*vec2.length) );
		}
		
	}
}